package com.grp6.game.controller;

import static org.junit.Assert.*;

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.List;

import org.junit.Test;

import com.grp6.game.model.IGameBoard;
import com.grp6.game.model.IGameModel;
import com.grp6.game.player.IComputerPlayer;
import com.grp6.game.player.IHumanPlayer;
import com.grp6.game.player.IPlayer;
import com.grp6.game.settings.IPreferences;
import com.grp6.game.ui.platform.IAbstractUIPlatformFactory;
import com.grp6.game.ui.platform.ICell;
import com.grp6.game.ui.platform.IDialog;

public class GameLordTest{

	private static boolean createdGameBuilder;
	private static boolean createdGameLifecycle;
	private static boolean createdUIPlatform;
	
	private static boolean throwOnPurposeException = false;
	private static class OnPurposeException extends RuntimeException{
		private static final long serialVersionUID = 1L;
	}

	@Test
	public void testMainA() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
		ByteArrayOutputStream errContent = new ByteArrayOutputStream();
		System.setErr(new PrintStream(errContent));
		GameLord.main(new String[0]);
		assertTrue(errContent.toString().toLowerCase().startsWith("synopse"));
	}
	
	@Test
	public void testMain() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
		new GameLord();//tweak to get more coverage
		
		GameLord.main(new String[]{
				"com.grp6.game.controller.GameLordTest$UIPlatformFactoryMock",
				"com.grp6.game.controller.GameLordTest$GameFactoryMock"});
		

		assertTrue(createdUIPlatform);
		assertTrue(createdGameBuilder);
		assertTrue(createdGameLifecycle);
	}
	
	@Test
	public void testMainC() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
		throwOnPurposeException = true;
		try{
			GameLord.main(new String[]{
				"com.grp6.game.controller.GameLordTest$UIPlatformFactoryMock",
				"com.grp6.game.controller.GameLordTest$GameFactoryMock"});
		}catch(OnPurposeException e){
			// we intend this exception to happen by enabling throwOnPurposeException
		}
	}

	public static class UIPlatformFactoryMock implements IAbstractUIPlatformFactory{

		public UIPlatformFactoryMock(){
			createdUIPlatform = true;
		}

		@Override
		public ICell createICell(int x, int y) {
			return null;
		}
	
		@Override
		public IDialog createIDialog() {
			// TODO Auto-generated method stub
			return null;
		}

		@Override
		public void cleanUp() {
			// TODO Auto-generated method stub
			
		}
		
	}

	public static class GameFactoryMock implements IAbstractGameFactory{		
		@Override
		public IGameLifecycle createLifecycle(IGameModel model) {
			return new IGameLifecycle() {
				@Override
				public void runLifecycle() { 
					if (throwOnPurposeException)
						throw new OnPurposeException();
				}
			};
		}
	
		@Override
		public IPreferences createPreferences(IAbstractUIPlatformFactory uifac) {
			return null;
		}
	
		@Override
		public IHumanPlayer createHumanPlayer() {
			return null;
		}
	
		@Override
		public IComputerPlayer createComputerPlayer() {
			return null;
		}
	
		@Override
		public IGameBuilder createGameBuilder(IAbstractUIPlatformFactory uifac) {
			createdGameBuilder = true;
			return new IGameBuilder() {
				@Override
				public IGameLifecycle build() {
					createdGameLifecycle = true;
					return createLifecycle(null);
				}
			};
		}

		@Override
		public <P extends IPlayer> IGameModel createGameModel(IGameBoard board,
				List<P> players) {
			// TODO Auto-generated method stub
			return null;
		}

		@Override
		public IGameBoard createGameBoard(IPreferences preferences) {
			// TODO Auto-generated method stub
			return null;
		}
	
	}

}
